package com.trifork.scala.script

import java.lang.String
import java.util.{Arrays, ServiceLoader}
import collection.Seq
import javax.script._

/**
 * User: nsthen
 * Date: 1/26/12
 */

class ScalaScriptEngineFactory extends ScriptEngineFactory {
  var globalBindings:Bindings = new SimpleBindings();

  def setGlobalBindings(bindings: Bindings) { globalBindings = bindings }

  val name = "scala"

  def getEngineName = "scala"

  def getEngineVersion = "1.0"

  def getExtensions = Arrays.asList("scala")

  def getMimeTypes = Arrays.asList("application/x-scala")

  def getNames = Arrays.asList(name)

  def getLanguageName = "scala"

  def getLanguageVersion = "2.9.1"

  def getParameter(key: String) = key match {
    case ScriptEngine.ENGINE => getEngineName
    case ScriptEngine.ENGINE_VERSION => getEngineVersion
    case ScriptEngine.LANGUAGE => getLanguageName
    case ScriptEngine.LANGUAGE_VERSION => getLanguageVersion
    case ScriptEngine.NAME => name
    case _ => null
  }

  def getOutputStatement(toDisplay: String) = "println(\"" + toDisplay + "\")"

  def newScriptContext():ScriptContext = {
    val scriptContext = new SimpleScriptContext()
    scriptContext.setBindings(globalBindings, ScriptContext.GLOBAL_SCOPE)
    scriptContext
  }

  def getScriptEngine = new ScalaScriptEngine(this)

  def getProgram(statements: String*) = statements.reduceLeft(_ + "\n" + _)

  def getMethodCallSyntax(obj: String, m: String, args: String*) = obj + "." + m + "(" + argsList(args) + ")"

  private def argsList(seq: Seq[String]): String = seq.map("\"" + _ + "\"").reduceLeft(_ + ", " + _)
}